package timing.ukulele.auth.controller;

import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import timing.ukulele.auth.security.SecurityUtils;
import timing.ukulele.auth.service.OptService;
import timing.ukulele.common.data.ResponseData;
import timing.ukulele.common.util.QRCodeUtil;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
 * 双因子认证操作流程
 * 1. 获取双因子绑定二维码
 * 3. Google Authenticator软件扫码生成
 */
@RestController
@Slf4j
@RequestMapping("/common/opt")
@Tag(name = "常规接口", description = "不需要登录的接口")
@ApiResponses(value = {
        @ApiResponse(responseCode = "1000", description = "成功", content = {@Content(mediaType = "application/json")}),
        @ApiResponse(responseCode = "1001", description = "失败", content = {@Content(mediaType = "application/json")}),
        @ApiResponse(responseCode = "3000", description = "业务处理失败", content = {@Content(mediaType = "application/json")})
})
public class OtpController {

    private final OptService optService;

    @Value("${ukulele.domain}")
    private String issuer;

    public OtpController(OptService optService) {
        this.optService = optService;
    }

    @GetMapping("/code")
    @Operation(summary = "获取otp码", description = "双因子认证的otp码")
    public void genQrCode(@RequestHeader("X-USER") String username, HttpServletResponse response) throws Exception {
        GoogleAuthenticator gAuth = new GoogleAuthenticator();
        final GoogleAuthenticatorKey key = gAuth.createCredentials();
        // 密钥
        String secretKey = key.getKey();

        String info = URLEncoder.encode(issuer + ":" + username, StandardCharsets.UTF_8);
        String code = String.format("otpauth://totp/%s?secret=%s", info, secretKey);
        OutputStream stream = response.getOutputStream();
        QRCodeUtil.encode(code, stream);
    }


    @GetMapping("/bind")
    @Operation(summary = "绑定otp码", description = "开启用户的双因子登录认证")
    public ResponseData<String> bindOtp(@RequestParam("username") String username, @RequestParam("password") String password, @RequestParam("secret") String secret) {
        // 对用户、密码、密钥进行解密
        String usernameDecrypted = SecurityUtils.decryptPassword(username);
        String passwordDecrypted = SecurityUtils.decryptPassword(password);
        String secretDecrypted = SecurityUtils.decryptPassword(secret);
        return optService.bindUserOtp(usernameDecrypted, passwordDecrypted, secretDecrypted);
    }

}
